#!/usr/bin/env python 
# -*- coding: utf-8 -*-
# @Time    : 2023/4/9 17:02
# @Author  : WJQ
# @Site    : 
# @File    : driver_wx.py
# @Software: PyCharm
import os
import re
import time, json
import traceback
from appium import webdriver
from appium.webdriver.common.touch_action import TouchAction
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

import conf
from browser.driver import DriverHandler
from browser.page import PageHandler
from utils.common import CrawlerLogger, find_webview_context
from utils.get_app_json import copy_Pkg_Down_bd, unpack_and_copy_json_bd


class DriverHandlerBd(DriverHandler):
    def __init__(self, applets_name):
        super().__init__(applets_name, 91)


    @classmethod
    def create(cls, applets_name):
        self = DriverHandlerBd(applets_name)
        return self

    def get_baidu_url( self ) -> str:
        page_source = self.driver.page_source
        # 使用正则表达式来提取AppID
        match = re.search(r'<base href="/data/user/0/com.baidu.swan/files/aiapps_folder/(.*?)/\d+//(.+?)">', page_source)
        if match :
            url = match.group(2)
            return url
        else :
            CrawlerLogger.debug("[-] Error getting url")
            return ""

    def get_baidu_appid( self ) -> str:
        if self.driver.current_context == "Native_APP":
            self.switch_to_webview_context()
        if conf.CLIENT_SIDE_CONF.WX_APP_BRAND == '-1':
            conf.CLIENT_SIDE_CONF.WX_APP_BRAND = find_webview_context()
        info_dict = self.driver.execute_script('return swan.getEnvInfoSync()')
        return info_dict['appKey']


    def find_top_window(self):
        '''
        切换成当前driver的window handle
        '''
        try:
            for window in self.driver.window_handles:
                self.driver.switch_to.window(window)
                if PageHandler.safe_find_element(self.driver, AppiumBy.XPATH, '//swan-page'):
                    # CrawlerLogger.info(f"{self.driver.path} is top window")
                    return
        except Exception as e:
            CrawlerLogger.debug(f"[-] Error finding top window: {e}")
            pass

    def switch_to_webview_context(self):
        '''
        切换成当前driver的window handle
        '''
        self.driver.switch_to.context('WEBVIEW_com.baidu.swan:swan' + conf.CLIENT_SIDE_CONF.WX_APP_BRAND)
        max_retries = 10
        retry_count = 0
        while retry_count < max_retries:
            try:
                self.find_top_window()
                break
            except Exception as e:
                CrawlerLogger.debug(f"[-] Error finding top window: {e}")
                retry_count += 1
                time.sleep(0.5)  # 等待 500 毫秒
        else:
            CrawlerLogger.debug("[-] Failed to find top window after max retries")

    def get_url( self ) -> (str, str):
        '''
        获取当前页面的url, 统一格式 [path, query]
        :return:
        '''
        if self.driver.current_context == "NATIVE_APP" :
            self.switch_to_webview_context()
        try :
            self.find_top_window()
            url = self.get_baidu_url()
            path = url.split("?")[0].split(".")[0]
            query = url.split("?")[1] if len(url.split("?")) > 1 else ""
            return path, query
        except Exception as e :
            CrawlerLogger.debug(f"Error getting driver title: {e}")
            return "pages/index/index", ""


    def get_all_pages ( self, file_path ) :
        with open(file_path, 'r', encoding='utf-8') as f :
            json_data = json.load(f)
        all_page = json_data['pages']
        return all_page

    def enter_mini_program(self, applets_name):
        '''
        进入小程序
        :param applets_name:
        :return:
        '''
        self.switch_to_native_app_context()
        self.driver.start_activity("com.baidu.swan", ".home.HomeActivity")
        # 等待页面加载完毕
        WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((AppiumBy.XPATH, "//*[@text='小程序示例']"))
        )
        # 进入小程序
        CrawlerLogger.info(f"[*] 进入小程序...")
        PageHandler.safe_click_element(self.driver, AppiumBy.ID, "com.baidu.swan:id/txt_swan_app_name")
        WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((AppiumBy.XPATH, "//*[@text='发现']"))
        )

        action = TouchAction(self.driver)
        time.sleep(1)
        action.tap(None, 720, 386).perform()
        input = PageHandler.safe_find_element(self.driver, AppiumBy.CLASS_NAME, "android.widget.EditText")
        input.send_keys(applets_name)
        time.sleep(2)
        action.tap(None, 1313, 395).perform()
        time.sleep(2)
        action.tap(None, 744, 744).perform()
        CrawlerLogger.info(f"[*] 进入小程序成功...")

        self.driver.quit()
        self.driver = webdriver.Remote("http://localhost:4723/wd/hub", self.CAPS)
        self.driver.implicitly_wait(5)

        WebDriverWait(self.driver, 10).until(
            EC.presence_of_element_located((AppiumBy.ID, "com.baidu.swan:id/titlebar_right_menu_img"))
        )

    def get_app_json ( self, applets_name ) :
        try:
            self.appid = self.get_baidu_appid()
            if not os.path.exists('./experiment/bd_files/pkgs_handle/' + self.applets_name) :
                os.mkdir('./experiment/bd_files/pkgs_handle/' + self.applets_name)
            copy_Pkg_Down_bd(self.appid, './experiment/bd_files/pkgs_handle/' + self.applets_name,
                             conf.CLIENT_SIDE_CONF.DEVICE_ID)
            unpack_and_copy_json_bd(applets_name, f'./experiment/bd_files/pkgs_handle/{self.applets_name}/{self.appid}', './experiment/app_json/bd')
            self.switch_to_native_app_context()
        except Exception as e:
            CrawlerLogger.error(f"[-] {traceback.format_exc()}")
            CrawlerLogger.debug(f"[-] {self.applets_name}未找到AppID")
            exit()

    def go_to_target_url ( self, target_title: str):
        if self.driver.current_context == "NATIVE_APP":
            self.switch_to_webview_context()
        current_url = self.get_url()[0]
        if target_title != current_url:
            # Construct the URL
            base_title = target_title.split(":")[1].split(".")[0] if ":" in target_title else target_title
            url = f"/{base_title}"
            # driver_handler.driver.execute_script('swan.navigateToSmartProgram({ appKey: "MzyRWoIRjWzq3pKItz5Dlt3Qhs7xSaKH", path: "pages/list/list"})')
            js_script = f'swan.reLaunch({{url: "{url}"}})'

            # self.driver_handler.find_top_window()
            CrawlerLogger.info(f"[*] js go to {target_title}...")
            self.driver.execute_script(js_script)
            time.sleep(2)
            self.find_top_window()